package com.zrc.japktool.apk.merge.dex;

import org.jf.dexlib2.iface.*;
import org.jf.dexlib2.iface.instruction.Instruction;
import org.jf.dexlib2.iface.instruction.formats.Instruction31i;
import org.jf.dexlib2.iface.instruction.formats.Instruction31t;
import org.jf.dexlib2.immutable.*;
import org.jf.dexlib2.immutable.instruction.ImmutableInstruction31i;
import org.jf.dexlib2.immutable.instruction.ImmutableInstruction31t;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

public class ModifiyDexClassID0 {

    public static void modifiyClassIds(List<ClassDef> targetList, Map<String, String> ids) {
        List<ClassDef> modifiedClassDefs = new ArrayList<>(targetList.size());
        for (ClassDef classDef : targetList) {
            //System.out.println("---------------"+classDef.getType());
            modifiedClassDefs.add(modifySingleClassDef(classDef, ids));
        }
        targetList.clear();
        targetList.addAll(modifiedClassDefs);
    }

    private static ClassDef modifySingleClassDef(ClassDef originalClass, Map<String, String> ids) {
        // 分别处理直接方法和虚拟方法
        List<Method> modifiedDirectMethods = new ArrayList<>();
        for (Method method : originalClass.getDirectMethods()) {
            modifiedDirectMethods.add(modifySingleMethod(method, ids));
        }

        List<Method> modifiedVirtualMethods = new ArrayList<>();
        for (Method method : originalClass.getVirtualMethods()) {
            modifiedVirtualMethods.add(modifySingleMethod(method, ids));
        }

        // 创建新的类定义，使用正确的ImmutableClassDef构造方法
        return new ImmutableClassDef(
                originalClass.getType(),
                originalClass.getAccessFlags(),
                originalClass.getSuperclass(),
                originalClass.getInterfaces(),
                originalClass.getSourceFile(),
                originalClass.getAnnotations(),
                originalClass.getStaticFields(),
                originalClass.getInstanceFields(),
                modifiedDirectMethods,
                modifiedVirtualMethods
        );
    }

    private static Method modifySingleMethod(Method originalMethod, Map<String, String> ids) {
        MethodImplementation originalImpl = originalMethod.getImplementation();
        if (originalImpl == null) {
            return originalMethod; // 无实现的方法无需修改
        }

        // 处理方法指令
        List<Instruction> modifiedInstructions = new ArrayList<>();
        for (Instruction instr : originalImpl.getInstructions()) {
            modifiedInstructions.add(modifyInstruction(instr, ids));
        }

        // 创建新的方法实现（明确使用ImmutableMethodImplementation）
        ImmutableMethodImplementation modifiedImpl = new ImmutableMethodImplementation(
                originalImpl.getRegisterCount(),
                modifiedInstructions,
                originalImpl.getTryBlocks(),
                originalImpl.getDebugItems()
        );

        // 关键修正：使用getParameters()而非getParameterTypes()，传递MethodParameter对象集合
        // 完全匹配ImmutableMethod构造方法的参数要求
        return new ImmutableMethod(
                originalMethod.getDefiningClass(),
                originalMethod.getName(),
                originalMethod.getParameters(), // 传递完整的参数对象（包含类型和注解）
                originalMethod.getReturnType(),
                originalMethod.getAccessFlags(),
                originalMethod.getAnnotations(),
                originalMethod.getHiddenApiRestrictions(),
                modifiedImpl
        );
    }

    private static Instruction modifyInstruction(Instruction originalInstr, Map<String, String> ids) {
        // 处理31i格式的常量指令（如const v0, 0x7f0b001c）
        if (originalInstr instanceof Instruction31i) {
            Instruction31i constInstr = (Instruction31i) originalInstr;
            // 关键修正：使用getNarrowLiteral()获取32位常量值，而非getWideLiteral()
            int originalValue = constInstr.getNarrowLiteral();
            // 生成与smali中格式一致的key（如0x7f0b001c）
            String key = String.format("0x%08x", originalValue);
            if (ids.containsKey(key)) {
                // 解析新值并创建替换指令
                String newValueStr = ids.get(key);
                int newValue = Integer.decode(newValueStr);
                // 返回新的不可变指令
                return new ImmutableInstruction31i(
                        constInstr.getOpcode(),
                        constInstr.getRegisterA(),
                        newValue
                );
            }
        }

        // 处理31t格式的跳转指令（如果需要）
        if (originalInstr instanceof Instruction31t) {
            Instruction31t jumpInstr = (Instruction31t) originalInstr;
            int originalValue = jumpInstr.getCodeOffset();
            String key = String.format("0x%08x", originalValue);
            if (ids.containsKey(key)) {
                String newValueStr = ids.get(key);
                int newValue = Integer.decode(newValueStr);
                return new ImmutableInstruction31t(
                        jumpInstr.getOpcode(),
                        jumpInstr.getRegisterA(),
                        newValue
                );
            }
        }

        // 不匹配的指令直接返回原指令
        return originalInstr;
    }

    public static String getTypePackage(String type) {
        if (type.startsWith("L") && type.endsWith(";")) {
            String className = type.substring(1, type.length() - 1);
            int lastSlashIndex = className.lastIndexOf('/');
            if (lastSlashIndex != -1) {
                return className.substring(0, lastSlashIndex).replace('/', '.');
            }
        }
        return "";
    }
}